﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using S7.Net;

namespace S7test
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        Plc plc;

        private void btn_Connect_Click(object sender, EventArgs e)
        {
            if (plc == null)
            {
                plc = new Plc((CpuType)Enum.Parse(typeof(CpuType), cmbbx_plcType.Text),
                               tb_IP.Text,
                               Convert.ToInt16(tb_rack.Text),
                               Convert.ToInt16(tb_slot.Text));
            }
            if (!plc.IsConnected)
            {
                plc.Open();
                btn_Connect.Text = "断开";
                textBox2.Text = textBox2.Text + "打开成功！\r\n";
            }
            else
            {
                plc.Close();
                btn_Connect.Text = "链接";
                textBox2.Text = textBox2.Text + "连接关闭！\r\n";
            }
        }

        private object GetValue(plcInfo plcInfo)
        {
            if (plc == null || !plc.IsConnected)
            {
                return "请先连接PLC设备！";
            }

            try
            {
                var plcData = new PLCAddress(plcInfo.DataPath);
                VarType useType = plcInfo.DataType;
                switch (useType)
                {
                    case VarType.Bit:
                        return plc.Read(plcInfo.DataPath);
                        break;
                    case VarType.Byte:
                        return plc.Read(plcInfo.DataPath);
                        break;
                    case VarType.Word:
                        return plc.Read(plcInfo.DataPath);
                        break;
                    case VarType.DWord:
                        return plc.Read(plcInfo.DataPath);
                        break;
                    case VarType.Int:
                        return plc.Read(plcData.DataType, plcData.DbNumber, plcData.StartByte, VarType.Int, 1);
                        break;
                    case VarType.DInt:
                        return plc.Read(plcData.DataType, plcData.DbNumber, plcData.StartByte, VarType.DInt, 1);
                        break;
                    case VarType.Real:
                        return plc.Read(plcData.DataType, plcData.DbNumber, plcData.StartByte, VarType.Real, 1);
                        break;
                    case VarType.LReal:
                        return plc.Read(plcData.DataType, plcData.DbNumber, plcData.StartByte, VarType.LReal, 1);
                        break;
                    case VarType.String:
                        byte count = (byte)plc.Read(plcData.DataType, plcData.DbNumber, plcData.StartByte + 1, VarType.Byte, 1);
                        return plc.Read(plcData.DataType, plcData.DbNumber, plcData.StartByte + 2, VarType.String, count);
                        break;
                    case VarType.S7String:
                        byte S7StringCount = (byte)plc.Read(plcData.DataType, plcData.DbNumber, plcData.StartByte + 1, VarType.Byte, 1);
                        return plc.Read(plcData.DataType, plcData.DbNumber, plcData.StartByte, VarType.S7String, S7StringCount);
                        break;
                    case VarType.S7WString:
                        short S7WStringCount = ((short)plc.Read(plcData.DataType, plcData.DbNumber, plcData.StartByte + 2, VarType.Int, 1));
                        return plc.Read(plcData.DataType, plcData.DbNumber, plcData.StartByte, VarType.S7WString, S7WStringCount);
                        break;
                    case VarType.S5Time:
                        return plc.Read(plcData.DataType, plcData.DbNumber, plcData.StartByte, VarType.S5Time, 1);
                        break;
                    case VarType.Counter:
                        break;
                    case VarType.DateTime:
                        return plc.Read(plcData.DataType, plcData.DbNumber, plcData.StartByte, VarType.DateTime, 1);
                        break;
                    case VarType.DateTimeLong:
                        return plc.Read(plcData.DataType, plcData.DbNumber, plcData.StartByte, VarType.DateTimeLong, 1);
                        break;
                    default:
                        throw new Exception("无输入");
                        break;
                }
                return null;
            }
            catch
            {
                return "获取数据失败！";
            }

        }

        private void btn_Read_Click(object sender, EventArgs e)
        {
            string test = cmbbx_dataType.Text;
            if (test == null)
                return;

            plcInfo plcInfo1;

            if (test == "Int")
            {
                plcInfo1 = new plcInfo() { DataPath = tb_dataReadAddress.Text, DataType = VarType.Int };
            }
            else
            {
                textBox2.Text = textBox2.Text + tb_dataReadAddress.Text + "内容：未指定类型\r\n" + test + "-";
                return;
            }

            string showStr = GetValue(plcInfo1).ToString();
            textBox2.Text = textBox2.Text + tb_dataReadAddress.Text + "内容：" + showStr + "\r\n";


            //foreach (var item in dic)
            //{
            //    string showStr = GetValue(item.Value).ToString();
            //    textBox2.Text = textBox2.Text + item.Value.DataPath + "内容：" + showStr + "\r\n";
            //}
        }

        private void SetValue(plcInfo plcInfo, object value)
        {

            try
            {
                var plcData = new PLCAddress(plcInfo.DataPath);
                VarType useType = plcInfo.DataType;

                switch (useType)
                {
                    case VarType.Bit:
                        plc.Write(plcData.DataType, plcData.DbNumber, plcData.StartByte, Convert.ToBoolean(value));
                        break;
                    case VarType.Byte:
                        plc.Write(plcData.DataType, plcData.DbNumber, plcData.StartByte, Convert.ToByte(value));
                        break;
                    case VarType.Word:
                        plc.Write(plcData.DataType, plcData.DbNumber, plcData.StartByte, Convert.ToUInt16(value));
                        break;
                    case VarType.DWord:
                        plc.Write(plcData.DataType, plcData.DbNumber, plcData.StartByte, Convert.ToUInt32(value));
                        break;
                    case VarType.Int:
                        plc.Write(plcData.DataType, plcData.DbNumber, plcData.StartByte, Convert.ToInt16(value));
                        break;
                    case VarType.DInt:
                        plc.Write(plcData.DataType, plcData.DbNumber, plcData.StartByte, Convert.ToInt32(value));
                        break;
                    case VarType.Real:
                        plc.Write(plcData.DataType, plcData.DbNumber, plcData.StartByte, Convert.ToSingle(value));
                        break;
                    case VarType.LReal:
                        plc.Write(plcData.DataType, plcData.DbNumber, plcData.StartByte, Convert.ToDouble(value));
                        break;
                    case VarType.String:
                        byte Count = Convert.ToByte(plcInfo.ByteCount == 0 ? 255 : plcInfo.ByteCount);
                        byte UsingCount = Convert.ToByte(value.ToString().Length);
                        byte[] stringArr = new byte[value.ToString().Length + 2];
                        stringArr[0] = Count;
                        stringArr[1] = UsingCount;
                        byte[] OstringArr = Encoding.ASCII.GetBytes(value.ToString());
                        for (int i = 0; i < OstringArr.Length; i++)
                        {
                            stringArr[2 + i] = OstringArr[i];
                        }
                        plc.Write(plcData.DataType, plcData.DbNumber, plcData.StartByte, stringArr);
                        break;
                    case VarType.S7String:
                        plc.Write(plcData.DataType, plcData.DbNumber, plcData.StartByte, value.ToString());
                        break;
                    case VarType.S7WString:
                        short wsCount = Convert.ToInt16(plcInfo.ByteCount == 0 ? 255 : plcInfo.ByteCount);
                        short wsUsingCount = Convert.ToInt16(value.ToString().Length);
                        byte[] wsstringArr = new byte[value.ToString().Length * 2 + 4];
                        wsstringArr[0] = Convert.ToByte(wsCount >> 8);
                        wsstringArr[1] = Convert.ToByte(wsCount & 0x00FF);
                        wsstringArr[2] = Convert.ToByte(wsUsingCount >> 8);
                        wsstringArr[3] = Convert.ToByte(wsUsingCount & 0x00FF);
                        byte[] wsOstringArr = Encoding.BigEndianUnicode.GetBytes(value.ToString());
                        for (int i = 0; i < wsOstringArr.Length; i++)
                        {
                            wsstringArr[4 + i] = wsOstringArr[i];
                        }
                        plc.Write(plcData.DataType, plcData.DbNumber, plcData.StartByte, wsstringArr);
                        break;
                    case VarType.S5Time:
                        short time = Convert.ToInt16(value);
                        plc.Write(plcData.DataType, plcData.DbNumber, plcData.StartByte, time);
                        break;
                    //case VarType.Counter:
                    //    break;
                    //case VarType.DateTime:
                    //    showStr = plc.Read(plcData.DataType, plcData.DbNumber, plcData.StartByte, VarType.DateTime, 1).ToString();
                    //    break;
                    //case VarType.DateTimeLong:
                    //    showStr = plc.Read(plcData.DataType, plcData.DbNumber, plcData.StartByte, VarType.DateTimeLong, 1).ToString();
                    //    break;
                    default:
                        break;
                }
            }
            catch
            {
                textBox2.Text = textBox2.Text + "写入设备失败！\r\n";
            }

        }

        private void btn_Write_Click(object sender, EventArgs e)
        {

            if (plc == null || !plc.IsConnected)
            {
                textBox2.Text = textBox2.Text + "请先连接PLC设备！\r\n" ;
                return;
            }

            string test = cmbbx_dataType.Text;
            if (test == null)
                return;

            plcInfo plcInfo1;

            if (test == "Int")
            {
                plcInfo1 = new plcInfo() { DataPath = textBox3.Text, DataType = VarType.Int };
            }
            else
            {
                textBox2.Text = textBox2.Text + textBox3.Text + "内容：未指定类型\r\n" + test + "-";
                return;
            }

            SetValue(plcInfo1, tb_WriteData.Text  );

            //object obj = new object();
            //foreach (var item in dic)
            //{

            //    switch (item.Value.DataType)
            //    {
            //        case VarType.Bit:
            //            obj = false;
            //            SetValue(item.Value, obj);
            //            break;
            //        case VarType.Byte:
            //            obj = 12;
            //            SetValue(item.Value, obj);
            //            break;
            //        case VarType.Word:
            //            obj = 100;
            //            SetValue(item.Value, obj);
            //            break;
            //        case VarType.DWord:
            //            obj = 100;
            //            SetValue(item.Value, obj);
            //            break;
            //        case VarType.Int:
            //            obj = -100;
            //            SetValue(item.Value, obj);
            //            break;
            //        case VarType.DInt:
            //            obj = -100;
            //            SetValue(item.Value, obj);
            //            break;
            //        case VarType.Real:
            //            obj = 10.22f;
            //            SetValue(item.Value, obj);
            //            break;
            //        case VarType.LReal:
            //            obj = 20.22;
            //            SetValue(item.Value, obj);
            //            break;
            //        case VarType.String:
            //            obj = "qwer";
            //            SetValue(item.Value, obj);
            //            break;
            //        //case VarType.S7String:
            //        //    break;
            //        case VarType.S7WString:
            //            obj = "嗡嗡嗡";
            //            SetValue(item.Value, obj);
            //            break;
            //        case VarType.S5Time:
            //            obj = 10;
            //            SetValue(item.Value, obj);
            //            break;
            //        //case VarType.Counter:
            //        //    break;
            //        //case VarType.DateTime:
            //        //    break;
            //        //case VarType.DateTimeLong:
            //        //    break;
            //        default:
            //            break;
            //    }

            //    textBox2.Text = textBox2.Text + item.Value.DataPath + "写入：" + obj.ToString() + "\r\n";
            //}

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            string[] cpuTypeArr = Enum.GetNames(typeof(CpuType));
            foreach (var item in cpuTypeArr)
            {
                cmbbx_plcType.Items.Add(item);
            }
            cmbbx_plcType.SelectedItem = CpuType.S71500.ToString();
            string[] dataTypeArr = Enum.GetNames(typeof(VarType));
            foreach (var item in dataTypeArr)
            {
                cmbbx_dataType.Items.Add(item);
            }
            cmbbx_dataType.SelectedItem = VarType.Int.ToString();

            dic.Add("bit", new plcInfo() { DataPath = "DB10.DBX0.0", DataType = VarType.Bit });
            dic.Add("byte", new plcInfo() { DataPath = "DB10.DBB1", DataType = VarType.Byte });
            dic.Add("word", new plcInfo() { DataPath = "DB10.DBW2", DataType = VarType.Word });
            dic.Add("dword", new plcInfo() { DataPath = "DB10.DBD4", DataType = VarType.DWord });
            dic.Add("int", new plcInfo() { DataPath = "DB10.DBW8", DataType = VarType.Int });
            dic.Add("dint", new plcInfo() { DataPath = "DB10.DBD10", DataType = VarType.DInt });
            dic.Add("real", new plcInfo() { DataPath = "DB10.DBD14", DataType = VarType.Real });
            dic.Add("lreal", new plcInfo() { DataPath = "DB10.DBX18.0", DataType = VarType.LReal });
            dic.Add("string", new plcInfo() { DataPath = "DB10.DBX26.0", DataType = VarType.String });
            dic.Add("s7wstring", new plcInfo() { DataPath = "DB10.DBX282.0", DataType = VarType.S7WString });
            //dic.Add("s5time", new plcInfo() { DataPath = "DB10.DBW794", DataType = VarType.S5Time });
            dic.Add("s5time", new plcInfo() { DataPath = "DB10.DBD794", DataType = VarType.S5Time });
        }

        Dictionary<string, plcInfo> dic = new Dictionary<string, plcInfo>();

        struct plcInfo
        {
            public string DataPath;
            public VarType DataType;
            public int ByteCount;
        }

    
    }
}
